<?php
namespace config\lib;

use config\lib\conf;

class Loader
{
    #用于判断类是否存在，节约性能
    public static $classMap = array();
    //Psr4 命名空间长度
    protected static $prefixLengthPsr4 = [];
    //Psr4 命名空间地址
    protected static $prefixDirPsr4 = [];

    /**
     * 自动加载类
     * @param $class
     * @return bool
     */
    public static function load($class)
    {
        if (isset($classMap[$class])){
            return true;
        }else{
            if ($file = self::findFile($class)){
                self::$classMap[$class] = $class;
                __require_file($file);
            }else{
                return false;
            }
        }
    }

    /*
     * Psr4 映射文件路径
     */
    public static function findFile($class)
    {
        //获取文件命名空间分组
        $first = $class[0];

        if(isset(self::$prefixLengthPsr4[$first])){
            foreach(self::$prefixLengthPsr4[$first] as $prefix => $length){
                if(0 == strpos($class,$prefix)){
                    if($file = self::$prefixDirPsr4[$prefix] . DS . substr($class,$length + 1) . EXT){
                        return $file;
                    }
                }
            }
        }
    }

    /*
     * 注册自动加载
     * @param
     */
    public static function register()
    {
        spl_autoload_register('config\lib\Loader::load',true,true);

        //添加命名空间地址
        self::addNamespace([
            'config' => CONFIG,
            'app'    => APP
        ]);
    }

    /*
     * 处理命名空间地址
     * @param $namespace array|string
     * @param $path string
     */
    public static function addNamespace($namespace,$path='')
    {
        if(is_array($namespace)){
            foreach ($namespace as $prefix => $path){
                self::addPsr4($prefix,$path);
            }
        }else{
            self::addPsr4($namespace,$path);
        }
    }

    /*
     * 注册命名空间地址
     * @param $prefix string
     * @param $path string
     */
    public static function addPsr4($prefix,$path)
    {
        if(!empty($prefix)){
            if(!isset(self::$prefixDirPsr4[$prefix])){
                self::$prefixDirPsr4[$prefix] = $path;
                self::$prefixLengthPsr4[$prefix[0]][$prefix] = strlen($prefix);
            }
        }
    }

    /*
     * 实例化控制器
     * @param $name string
     * @param $layer string
     */
    public static function controller($name,$layer = 'controller')
    {

        list($module,$class) = self::getModuleAndClass($name,$layer);

        if(class_exists($class)){
            //执行请求
            return App::invokeClass($class);
        }

        echo 'action not exists:'.$class;exit;
    }

    /*
     * 解析模块和类名
     * @param $name string
     * @param $layer string
     */
    public static function getModuleAndClass($name,$layer)
    {
        $module = Request::instance()->module();

        $array = explode('\\', str_replace(['/', '.'], '\\', $name));
        $class = array_pop($array);
        $path  = $array ? implode('\\', $array) . '\\' : '';

        $class = ($module ? $module . '\\' : '') .
            $layer . '\\' . $path . $class;

        return [$module,$class];
    }

}

//返回引入文件
function __include_file($file)
{
    return include $file;
}

//返回引入文件
function __require_file($file)
{
    return require $file;
}
